home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 001-025 / disk_022 / pemacs / random.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  13KB  |  401 lines

  1. /*
  2.  * This file contains the command processing functions for a number of random
  3.  * commands. There is no functional grouping here, for sure.
  4.  */
  5.  
  6. #include        <stdio.h>
  7. #include        "ed.h"
  8.  
  9. int     tabsize;                        /* Tab size (0: use real tabs)  */
  10.  
  11. /*
  12.  * Toggle word wrap.
  13.  */
  14. togglewordwrap(f, n)
  15. {
  16.     if( wordwrap) {
  17.     wordwrap = FALSE;
  18.     mlwrite( "Word wrap off");
  19.     } else {
  20.     wordwrap = TRUE;
  21.     mlwrite( "Word wrap on");
  22.     }
  23.         return(TRUE);
  24. }
  25.  
  26. /*
  27.  * Set fill column to n. 
  28.  */
  29. setfillcol(f, n)
  30. {
  31.         fillcol = n;
  32.         return(TRUE);
  33. }
  34.  
  35. /*
  36.  * Display the current position of the cursor, in origin 1 X-Y coordinates,
  37.  * the character that is under the cursor (in octal), and the fraction of the
  38.  * text that is before the cursor. The displayed column is not the current
  39.  * column, but the column that would be used on an infinite width display.
  40.  * Normally this is bound to "C-X =".
  41.  */
  42. showcpos(f, n)
  43. {
  44.         register LINE   *clp;
  45.         register long   nch;
  46.         register int    cbo;
  47.         register long   nbc;
  48.         register int    cac;
  49.         register int    ratio;
  50.         register int    col;
  51.         register int    i;
  52.         register int    c;
  53.  
  54.         clp = lforw(curbp->b_linep);            /* Grovel the data.     */
  55.         cbo = 0;
  56.         nch = 0;
  57.         for (;;) {
  58.                 if (clp==curwp->w_dotp && cbo==curwp->w_doto) {
  59.                         nbc = nch;
  60.                         if (cbo == llength(clp))
  61.                                 cac = '\n';
  62.                         else
  63.                                 cac = lgetc(clp, cbo);
  64.                 }
  65.                 if (cbo == llength(clp)) {
  66.                         if (clp == curbp->b_linep)
  67.                                 break;
  68.                         clp = lforw(clp);
  69.                         cbo = 0;
  70.                 } else
  71.                         ++cbo;
  72.                 ++nch;
  73.         }
  74.         col = getccol(FALSE);                   /* Get real column.     */
  75.         ratio = 0;                              /* Ratio before dot.    */
  76.         if (nch != 0)
  77.                 ratio = (100L*nbc) / nch;
  78.         mlwrite("X=%d Y=%d CH=0x%x .=%D (%d%% of %D)",
  79.                 col+1, currow+1, cac, nbc, ratio, nch);
  80.         return (TRUE);
  81. }
  82.  
  83. /*
  84.  * Return current column.  Stop at first non-blank given TRUE argument.
  85.  */
  86. getccol(bflg)
  87. int bflg;
  88. {
  89.         register int c, i, col;
  90.         col = 0;
  91.         for (i=0; i<curwp->w_doto; ++i) {
  92.                 c = lgetc(curwp->w_dotp, i);
  93.                 if (bflg && c!=' ' && c!='\t')
  94.                         break;
  95.                 if (c == '\t')
  96.                         col |= 0x07;
  97.                 else if (c<0x20 || c==0x7F)
  98.                         ++col;
  99.                 ++col;
  100.         }
  101.         return(col);
  102. }
  103.  
  104. /*
  105.  * Twiddle the two characters on either side of dot. If dot is at the end of
  106.  * the line twiddle the two characters before it. Return with an error if dot
  107.  * is at the beginning of line; it seems to be a bit pointless to make this
  108.  * work. This fixes up a very common typo with a single stroke. Normally bound
  109.  * to "C-T". This always works within a line, so "WFEDIT" is good enough.
  110.  */
  111. twiddle(f, n)
  112. {
  113.         register LINE   *dotp;
  114.         register int    doto;
  115.         register int    cl;
  116.         register int    cr;
  117.  
  118.         dotp = curwp->w_dotp;
  119.         doto = curwp->w_doto;
  120.         if (doto==llength(dotp) && --doto<0)
  121.                 return (FALSE);
  122.         cr = lgetc(dotp, doto);
  123.         if (--doto < 0)
  124.                 return (FALSE);
  125.         cl = lgetc(dotp, doto);
  126.         lputc(dotp, doto+0, cr);
  127.         lputc(dotp, doto+1, cl);
  128.         lchange(WFEDIT);
  129.         return (TRUE);
  130. }
  131.  
  132. /*
  133.  * Quote the next character, and insert it into the buffer. All the characters
  134.  * are taken literally, with the exception of the newline, which always has
  135.  * its line splitting meaning. The character is always read, even if it is
  136.  * inserted 0 times, for regularity. Bound to "M-Q" (for me) and "C-Q" (for
  137.  * Rich, and only on terminals that don't need XON-XOFF).
  138.  */
  139. quote(f, n)
  140. {
  141.         register int    s;
  142.         register int    c;
  143.  
  144.         c = (*term.t_getchar)();
  145.         if (n < 0)
  146.                 return (FALSE);
  147.         if (n == 0)
  148.                 return (TRUE);
  149.         if (c == '\n') {
  150.                 do {
  151.                         s = lnewline();
  152.                 } while (s==TRUE && --n);
  153.                 return (s);
  154.         }
  155.         return (linsert(n, c));
  156. }
  157.  
  158. /*
  159.  * Set tab size if given non-default argument (n <> 1).  Otherwise, insert a
  160.  * tab into file.  If given argument, n, of zero, change to true tabs.
  161.  * If n > 1, simulate tab stop every n-characters using spaces. This has to be
  162.  * done in this slightly funny way because the tab (in ASCII) has been turned
  163.  * into "C-I" (in 10 bit code) already. Bound to "C-I".
  164.  */
  165. tab(f, n)
  166. {
  167.         if (n < 0)
  168.                 return (FALSE);
  169.         if (n == 0 || n > 1) {
  170.                 tabsize = n;
  171.                 return(TRUE);
  172.         }
  173.         if (! tabsize)
  174.                 return(linsert(1, '\t'));
  175.         return(linsert(tabsize - (getccol(FALSE) % tabsize), ' '));
  176. }
  177.  
  178. /*
  179.  * Open up some blank space. The basic plan is to insert a bunch of newlines,
  180.  * and then back up over them. Everything is done by the subcommand
  181.  * procerssors. They even handle the looping. Normally this is bound to "C-O".
  182.  */
  183. openline(f, n)
  184. {
  185.         register int    i;
  186.         register int    s;
  187.  
  188.         if (n < 0)
  189.                 return (FALSE);
  190.         if (n == 0)
  191.                 return (TRUE);
  192.         i = n;                                  /* Insert newlines.     */
  193.         do {
  194.                 s = lnewline();
  195.         } while (s==TRUE && --i);
  196.         if (s == TRUE)                          /* Then back up overtop */
  197.                 s = backchar(f, n);             /* of them all.         */
  198.         return (s);
  199. }
  200.  
  201. /*
  202.  * Insert a newline. Bound to "C-M". If you are at the end of the line and the
  203.  * next line is a blank line, just move into the blank line. This makes "C-O"
  204.  * and "C-X C-O" work nicely, and reduces the ammount of screen update that
  205.  * has to be done. This would not be as critical if screen update were a lot
  206.  * more efficient.
  207.  */
  208. newline(f, n)
  209. {
  210.         int nicol;
  211.         register LINE   *lp;
  212.         register int    s;
  213.  
  214.         if (n < 0)
  215.                 return (FALSE);
  216.         while (n--) {
  217.                 lp = curwp->w_dotp;
  218.                 if (llength(lp) == curwp->w_doto
  219.                 && lp != curbp->b_linep
  220.                 && llength(lforw(lp)) == 0) {
  221.                         if ((s=forwchar(FALSE, 1)) != TRUE)
  222.                                 return (s);
  223.                 } else if ((s=lnewline()) != TRUE)
  224.                         return (s);
  225.         }
  226.         return (TRUE);
  227. }
  228.  
  229. /*
  230.  * Delete blank lines around dot. What this command does depends if dot is
  231.  * sitting on a blank line. If dot is sitting on a blank line, this command
  232.  * deletes all the blank lines above and below the current line. If it is
  233.  * sitting on a non blank line then it deletes all of the blank lines after
  234.  * the line. Normally this command is bound to "C-X C-O". Any argument is
  235.  * ignored.
  236.  */
  237. deblank(f, n)
  238. {
  239.         register LINE   *lp1;
  240.         register LINE   *lp2;
  241.         register int    nld;
  242.  
  243.         lp1 = curwp->w_dotp;
  244.         while (llength(lp1)==0 && (lp2=lback(lp1))!=curbp->b_linep)
  245.                 lp1 = lp2;
  246.         lp2 = lp1;
  247.         nld = 0;
  248.         while ((lp2=lforw(lp2))!=curbp->b_linep && llength(lp2)==0)
  249.                 ++nld;
  250.         if (nld == 0)
  251.                 return (TRUE);
  252.         curwp->w_dotp = lforw(lp1);
  253.         curwp->w_doto = 0;
  254.         return (ldelete(nld));
  255. }
  256.  
  257. /*
  258.  * Insert a newline, then enough tabs and spaces to duplicate the indentation
  259.  * of the previous line. Assumes tabs are every eight characters. Quite simple.
  260.  * Figure out the indentation of the current line. Insert a newline by calling
  261.  * the standard routine. Insert the indentation by inserting the right number
  262.  * of tabs and spaces. Return TRUE if all ok. Return FALSE if one of the
  263.  * subcomands failed. Normally bound to "C-J".
  264.  */
  265. indent(f, n)
  266. {
  267.         register int    nicol;
  268.         register int    c;
  269.         register int    i;
  270.  
  271.         if (n < 0)
  272.                 return (FALSE);
  273.         while (n--) {
  274.                 nicol = 0;
  275.                 for (i=0; i<llength(curwp->w_dotp); ++i) {
  276.                         c = lgetc(curwp->w_dotp, i);
  277.                         if (c!=' ' && c!='\t')
  278.                                 break;
  279.                         if (c == '\t')
  280.                                 nicol |= 0x07;
  281.                         ++nicol;
  282.                 }
  283.                 if (lnewline() == FALSE
  284.                 || ((i=nicol/8)!=0 && linsert(i, '\t')==FALSE)
  285.                 || ((i=nicol%8)!=0 && linsert(i,  ' ')==FALSE))
  286.                         return (FALSE);
  287.         }
  288.         return (TRUE);
  289. }
  290.  
  291. /*
  292.  * Delete forward. This is real easy, because the basic delete routine does
  293.  * all of the work. Watches for negative arguments, and does the right thing.
  294.  * If any argument is present, it kills rather than deletes, to prevent loss
  295.  * of text if typed with a big argument. Normally bound to "C-D".
  296.  */
  297. forwdel(f, n)
  298. {
  299.         if (n < 0)
  300.                 return (backdel(f, -n));
  301.         if (f != FALSE) {                       /* Really a kill.       */
  302.                 if ((lastflag&CFKILL) == 0)
  303.                         kdelete();
  304.                 thisflag |= CFKILL;
  305.         }
  306.         return (ldelete(n, f));
  307. }
  308.  
  309. /*
  310.  * Delete backwards. This is quite easy too, because it's all done with other
  311.  * functions. Just move the cursor back, and delete forwards. Like delete
  312.  * forward, this actually does a kill if presented with an argument. Bound to
  313.  * both "RUBOUT" and "C-H".
  314.  */
  315. backdel(f, n)
  316. {
  317.         register int    s;
  318.  
  319.         if (n < 0)
  320.                 return (forwdel(f, -n));
  321.         if (f != FALSE) {                       /* Really a kill.       */
  322.                 if ((lastflag&CFKILL) == 0)
  323.                         kdelete();
  324.                 thisflag |= CFKILL;
  325.         }
  326.         if ((s=backchar(f, n)) == TRUE)
  327.                 s = ldelete(n, f);
  328.         return (s);
  329. }
  330.  
  331. /*
  332.  * Kill text. If called without an argument, it kills from dot to the end of
  333.  * the line, unless it is at the end of the line, when it kills the newline.
  334.  * If called with an argument of 0, it kills from the start of the line to dot.
  335.  * If called with a positive argument, it kills from dot forward over that
  336.  * number of newlines. If called with a negative argument it kills backwards
  337.  * that number of newlines. Normally bound to "C-K".
  338.  */
  339. kill(f, n)
  340. {
  341.         register int    chunk;
  342.         register LINE   *nextp;
  343.  
  344.         if ((lastflag&CFKILL) == 0)             /* Clear kill buffer if */
  345.                 kdelete();                      /* last wasn't a kill.  */
  346.         thisflag |= CFKILL;
  347.         if (f == FALSE) {
  348.                 chunk = llength(curwp->w_dotp)-curwp->w_doto;
  349.                 if (chunk == 0)
  350.                         chunk = 1;
  351.         } else if (n == 0) {
  352.                 chunk = curwp->w_doto;
  353.                 curwp->w_doto = 0;
  354.         } else if (n > 0) {
  355.                 chunk = llength(curwp->w_dotp)-curwp->w_doto+1;
  356.                 nextp = lforw(curwp->w_dotp);
  357.                 while (--n) {
  358.                         if (nextp == curbp->b_linep)
  359.                                 return (FALSE);
  360.                         chunk += llength(nextp)+1;
  361.                         nextp = lforw(nextp);
  362.                 }
  363.         } else {
  364.                 mlwrite("neg kill");
  365.                 return (FALSE);
  366.         }
  367.         return (ldelete(chunk, TRUE));
  368. }
  369.  
  370. /*
  371.  * Yank text back from the kill buffer. This is really easy. All of the work
  372.  * is done by the standard insert routines. All you do is run the loop, and
  373.  * check for errors. Bound to "C-Y". The blank lines are inserted with a call
  374.  * to "newline" instead of a call to "lnewline" so that the magic stuff that
  375.  * happens when you type a carriage return also happens when a carriage return
  376.  * is yanked back from the kill buffer.
  377.  */
  378. yank(f, n)
  379. {
  380.         register int    c;
  381.         register int    i;
  382.         extern   int    kused;
  383.  
  384.         if (n < 0)
  385.                 return (FALSE);
  386.         while (n--) {
  387.                 i = 0;
  388.                 while ((c=kremove(i)) >= 0) {
  389.                         if (c == '\n') {
  390.                                 if (newline(FALSE, 1) == FALSE)
  391.                                         return (FALSE);
  392.                         } else {
  393.                                 if (linsert(1, c) == FALSE)
  394.                                         return (FALSE);
  395.                         }
  396.                         ++i;
  397.                 }
  398.         }
  399.         return (TRUE);
  400. }
  401.